package com.able.concurrency.t4;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * @author abel.he
 * @data 2018/10/25 15:59
 * @describe 延时队列
 *  延时队列。根据比较机制，实现自定义处理顺序的队列。 常用于定时任务。如：定时关机
 */
public class Test6_DelayQueue {

    static BlockingQueue<MyTest6> blockingQueue = new DelayQueue();

    public static void main(String[] args) {
        long time = System.currentTimeMillis();
        MyTest6 test61 = new MyTest6(time + 2000);
        MyTest6 test62 = new MyTest6(time + 1000);
        MyTest6 test63 = new MyTest6(time + 3000);
        MyTest6 test64 = new MyTest6(time + 2500);
        MyTest6 test65 = new MyTest6(time + 1500);

        try {
            blockingQueue.put(test61);
            blockingQueue.put(test62);
            blockingQueue.put(test63);
            blockingQueue.put(test64);
            blockingQueue.put(test65);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(blockingQueue);
        System.out.println(time);


        int size = blockingQueue.size();
        System.out.println(size);
        for (int i = 0; i < size; i++) {
            try {
                System.out.println(i);
                System.out.println(blockingQueue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

}

class MyTest6 implements Delayed {

    long time ;

    public MyTest6(long time) {
        this.time = time;
    }

    /**
     * 获取计划时长的方法。
     * 根据参数TimeUnit来决定，如何返回结果值。
     */
    @Override
    public long getDelay(TimeUnit unit) {
        return unit.convert(time - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
    }

    /**
     * 比较大小。自动实现升序
     * 建议和getDelay方法配合完成。
     * 如果在DelayQueue是需要按时间完成的计划任务，必须配合getDelay方法完成。
     */
    @Override
    public int compareTo(Delayed o) {
        return (int)(this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
    }

    @Override
    public String toString() {
        return "Task compare value is : " + this.time;

    }
}